package com.zbkj.admin.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.SecureUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.zbkj.admin.mapper1.EbPaySecretKeyMapper;
import com.zbkj.admin.pojo.EbPaySecretKeyEntity;
import com.zbkj.admin.service.EbPaySecretKeyService;
import net.dreamlu.mica.core.result.R;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.time.LocalDateTime;
import java.util.Enumeration;
import java.util.Objects;

/**
 * 第三方支付秘钥信息 服务层实现。
 *
 * @author mybatis-flex-helper automatic generation
 * @since 1.0
 */
@Service
public class EbPaySecretKeyServiceImpl extends ServiceImpl<EbPaySecretKeyMapper, EbPaySecretKeyEntity> implements EbPaySecretKeyService {

    /**
     * 创建秘钥信息
     *
     * @param ebPaySecretKeyEntity 秘钥信息
     * @return 创建结果
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public R<Boolean> createSecretKey(EbPaySecretKeyEntity ebPaySecretKeyEntity) {
        MultipartFile merchantPayPublicKeyFile = ebPaySecretKeyEntity.getMerchantPayPublicKeyFile();
        MultipartFile merchantPayPrivateKeyFile = ebPaySecretKeyEntity.getMerchantPayPrivateKeyFile();
        if (Objects.nonNull(merchantPayPublicKeyFile) && Objects.isNull(merchantPayPrivateKeyFile)) {
            return R.fail("请上传私钥文件");
        }
        if (Objects.nonNull(merchantPayPrivateKeyFile) && Objects.isNull(ebPaySecretKeyEntity.getMerchantPayPrivateKeyPassword())) {
            return R.fail("请输入私钥密码");
        }
        if (Objects.isNull(merchantPayPublicKeyFile) && Objects.isNull(merchantPayPrivateKeyFile)
                && Objects.isNull(ebPaySecretKeyEntity.getMerchantPayPrivateKey())) {
            return R.fail("请上传公钥私钥文件或者私钥字符串信息");
        }
        if (Objects.nonNull(merchantPayPublicKeyFile)) {
            if (!merchantPayPublicKeyFile.getName().endsWith(".cer")) {
                return R.fail("请上传正确的cer公钥文件");
            }
            try {
                Certificate certificate = SecureUtil.readCertificate("X.509", merchantPayPublicKeyFile.getInputStream());
                if (Objects.nonNull(certificate)) {
                    byte[] encoded = certificate.getPublicKey().getEncoded();
                    String encode = Base64.encode(encoded);
                    ebPaySecretKeyEntity.setMerchantPayPublicKey(encode);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        if (Objects.nonNull(merchantPayPrivateKeyFile) && StrUtil.isNotBlank(ebPaySecretKeyEntity.getMerchantPayPrivateKeyPassword())) {
            if (!merchantPayPrivateKeyFile.getName().endsWith(".pfx")
                    || !merchantPayPrivateKeyFile.getName().endsWith(".p12")
                    || !merchantPayPrivateKeyFile.getName().endsWith(".pem")
                    && !merchantPayPrivateKeyFile.getName().endsWith(".cer")
            ) {
                return R.fail("请上传正确的pfx、p12、pem公钥文件");
            }
            try {
                char[] pass = ebPaySecretKeyEntity.getMerchantPayPrivateKeyPassword().toCharArray();
                KeyStore keyStore = KeyUtil.readKeyStore("PKCS12", merchantPayPrivateKeyFile.getInputStream(), pass);
                Enumeration<String> enumas = keyStore.aliases();
                String keyAlias = null;
                if (enumas.hasMoreElements()) {
                    keyAlias = enumas.nextElement();
                }
                PrivateKey key = (PrivateKey) keyStore.getKey(keyAlias, pass);
                if (Objects.nonNull(key)) {
                    byte[] encoded = key.getEncoded();
                    String encode = Base64.encode(encoded);
                    ebPaySecretKeyEntity.setMerchantPayPrivateKey(encode);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        saveOrUpdate(ebPaySecretKeyEntity.setCreateTime(LocalDateTime.now()).setUpdateTime(LocalDateTime.now()));
        return R.success(true);
    }

    /**
     * 根据商户号或者主键id获取秘钥信息
     *
     * @param merchantPayNo 商户号(主键id)
     * @return 秘钥信息
     */
    @Override
    public R<EbPaySecretKeyEntity> getSecretKey(Long merchantPayNo) {
        return R.success(getOne(from().where(EbPaySecretKeyEntity::getId).eq(merchantPayNo)
                .or(EbPaySecretKeyEntity::getMerchantPayNo).eq(merchantPayNo)));
    }

    /**
     * 获取秘钥信息分页
     *
     * @param pageNo   页码
     * @param pageSize 页大小
     * @return 分页数据
     */
    @Override
    public R<PageInfo<EbPaySecretKeyEntity>> getPageInfo(Integer pageNo, Integer pageSize, Long merchantPayNo, String merchantName) {
        return R.success(PageHelper.startPage(pageNo, pageSize).doSelectPageInfo(() -> list(from().where(EbPaySecretKeyEntity::getMerchantPayNo)
                .eq(merchantPayNo).and(EbPaySecretKeyEntity::getMerchantName).like(merchantName))));
    }
}